package bll

import (
	"context"
	"manager/utils"
	"manager/utils/goroutine_pool"

	"manager/event"
	"manager/model"
	"manager/model/entity"
	"manager/store"
	"manager/store/postgres"
	"time"
)

type EnOperatorType int

const (
	EnAdd EnOperatorType = iota + 1
	EnUpdate
	EnDel
)

type tableLog struct {
	iTableLog store.ITableLog
}

var TableLog = &tableLog{
	iTableLog: postgres.TableLog,
}

func (a *tableLog) init() func() {
	return func() {}
}

func (a *tableLog) onEvent(*event.Data) {}

// AddOperatorLog 添加操作日志
func (a *tableLog) AddOperatorLog(operatorId int64, operatorType EnOperatorType, tableName, detail string) error {
	goroutine_pool.GetPoolV2("log").Push(nil, func(data interface{}) error {
		return a.Create(context.Background(), &model.TableLogCreateRequest{
			OperatorId: operatorId,
			Type:       int(operatorType),
			TableName:  tableName,
			Comment:    detail,
		})
	})

	return nil
}

// Create 创建
func (a *tableLog) Create(ctx context.Context, in *model.TableLogCreateRequest) error {
	var (
		err error
	)

	// 构建创建现场数据
	c := buildTableLog(in)
	_, err = a.iTableLog.Create(ctx, c)
	return err
}

// Update 更新
func (a *tableLog) Update(ctx context.Context, in *model.TableLogUpdateRequest) error {
	var (
		dict = make(map[string]interface{})
	)

	updateAt := time.Now().Unix()
	in.UpdatedAt = &updateAt

	if in.OperatorId != nil {
		dict["operator_id"] = in.OperatorId
	}

	if in.Type != nil {
		dict["type"] = in.Type
	}

	if in.TableName != nil {
		dict["table_name"] = in.TableName
	}

	if in.Comment != nil {
		dict["comment"] = in.Comment
	}

	if in.UpdatedAt != nil {
		dict["updated_at"] = in.UpdatedAt
	}

	// do other update here

	return a.iTableLog.Update(ctx, in.Id, dict)
}

// Delete 删除
func (a *tableLog) Delete(ctx context.Context, in *model.TableLogDeleteRequest) error {
	return a.iTableLog.Delete(ctx, in.Id)
}

// List 列表查询
func (a *tableLog) List(ctx context.Context, in *model.TableLogListRequest) (*model.TableLogListResponse, error) {
	var (
		err   error
		total int
		list  []*entity.TableLog
		out   = &model.TableLogListResponse{}
	)

	if total, list, err = a.iTableLog.List(ctx, in); err != nil {
		return nil, err
	}

	out.Total = total
	out.List = model.TableLogsEntityToDto(list)

	return out, nil
}

// Find 列表查询
func (a *tableLog) Find(ctx context.Context, in *model.TableLogInfoRequest) (*model.TableLogInfo, error) {
	var (
		err  error
		data *entity.TableLog
		out  = &model.TableLogInfo{}
	)

	if data, err = a.iTableLog.Find(ctx, in); err != nil {
		return nil, err
	}

	out = model.TableLogEntityToDto(data)
	return out, nil
}

// buildTableLog 构建创建数据现场
func buildTableLog(in *model.TableLogCreateRequest) *entity.TableLog {
	// todo: check the entity is required
	return &entity.TableLog{

		OperatorId: in.OperatorId,

		Type: in.Type,

		Table: in.TableName,

		Comment: in.Comment,

		CreatedAt: utils.TimeFormat(time.Now()),

		UpdatedAt: utils.TimeFormat(time.Now()),
	}
}
